-
Notifications
You must be signed in to change notification settings - Fork 814
feat: added csv functionalities in gyroscope screen. #2818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's GuideThis pull request adds CSV recording and export capabilities to the gyroscope screen with user-prompted filenames, refactors the GyroscopeProvider lifecycle and CsvService storage logic, removes manual permission requests, enhances the logged data chart with relative time and dynamic formatting, and cleans up related manifest permissions. Entity relationship diagram for gyroscope CSV data structureerDiagram
GYROSCOPE_CSV {
string Timestamp
string DateTime
double ReadingsX
double ReadingsY
double ReadingsZ
double Latitude
double Longitude
}
Class diagram for updated GyroscopeProvider and CsvServiceclassDiagram
class GyroscopeProvider {
- StreamSubscription<GyroscopeEvent>? _gyroscopeSubscription
- GyroscopeEvent _gyroscopeEvent
- List<double> _xData
- List<double> _yData
- List<double> _zData
- double _xMin, _xMax, _yMin, _yMax, _zMin, _zMax
- bool _isRecording
- List<List<dynamic>> _recordedData
+ double get xValue
+ double get yValue
+ double get zValue
+ bool get isListening
+ bool get isRecording
+ void initializeSensors()
+ void disposeSensors()
+ void startRecording()
+ List<List<dynamic>> stopRecording()
+ List<FlSpot> getAxisData(String axis)
}
class CsvService {
+ Future<Directory> getInstrumentDirectory(String instrumentName)
+ Future<File?> saveCsvFile(String instrumentName, String fileName, List<List<dynamic>> data)
+ Future<void> writeMetaData(String instrumentName, List<List<dynamic>> data)
}
GyroscopeProvider --> CsvService : uses for CSV export
Class diagram for updated LoggedDataChartScreenclassDiagram
class LoggedDataChartScreen {
+ String fileName
+ List<List<dynamic>> data
+ String xAxisLabel
+ String yAxisLabel
+ int xDataColumnIndex
+ int yDataColumnIndex
+ String? instrumentName
+ Widget build(BuildContext context)
+ Widget _buildChart(...)
+ Widget _sideTitleWidgets(...)
}
LoggedDataChartScreen o-- "1" LoggedDataScreen : navigated from
LoggedDataChartScreen *-- "1" GyroscopeProvider : uses data
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Build successful. APKs to test: https://github.com/fossasia/pslab-app/actions/runs/17008873042/artifacts/3779779618 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @Yugesh-Kumar-S - I've reviewed your changes - here's some feedback:
- Provide a meaningful default filename (e.g. “gyroscope_YYYYMMDD_HHMMSS”) in the save dialog so users don’t have to start with an empty string.
- Extract the chart‐building logic in LoggedDataChartScreen (axis selector, side title widget, interval calculations) into smaller helper methods or widgets to improve readability.
- Instead of manually instantiating and disposing GyroscopeProvider in initState/dispose, consider wrapping the screen in a ChangeNotifierProvider factory to let provider handle lifecycle automatically.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Provide a meaningful default filename (e.g. “gyroscope_YYYYMMDD_HHMMSS”) in the save dialog so users don’t have to start with an empty string.
- Extract the chart‐building logic in LoggedDataChartScreen (axis selector, side title widget, interval calculations) into smaller helper methods or widgets to improve readability.
- Instead of manually instantiating and disposing GyroscopeProvider in initState/dispose, consider wrapping the screen in a ChangeNotifierProvider factory to let provider handle lifecycle automatically.
## Individual Comments
### Comment 1
<location> `lib/view/logged_data_chart_screen.dart:221` </location>
<code_context>
double minX = 0;
+ double? startTime;
for (int i = 1; i < widget.data.length; i++) {
final row = widget.data[i];
if (row.length > widget.xDataColumnIndex &&
row.length > widget.yDataColumnIndex) {
final xValue = _parseDouble(row[widget.xDataColumnIndex]);
- final yValue = _parseDouble(row[widget.yDataColumnIndex]);
+ final yValue = _parseDouble(row[_getYDataColumnIndex()]);
if (xValue != null && yValue != null) {
- spots.add(FlSpot(xValue, yValue));
+ if (startTime == null) {
+ startTime = xValue;
+ minX = 0;
+ }
+
+ final relativeTime = ((xValue - startTime) / 1000.0);
+
+ spots.add(FlSpot(relativeTime, yValue));
</code_context>
<issue_to_address>
Assumes xValue is in milliseconds for time axis calculation.
If the data source or CSV format changes, this assumption may cause incorrect time calculations. Please validate or document the expected time unit for xValue.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
if (startTime == null) {
startTime = xValue;
minX = 0;
}
final relativeTime = ((xValue - startTime) / 1000.0);
spots.add(FlSpot(relativeTime, yValue));
=======
if (startTime == null) {
startTime = xValue;
minX = 0;
}
// Assumes xValue is in milliseconds. If the data source or CSV format changes,
// this calculation may be incorrect. Please ensure xValue is in milliseconds.
assert(xValue >= 0 && startTime >= 0, 'xValue and startTime should be non-negative and in milliseconds.');
final relativeTime = ((xValue - startTime) / 1000.0);
spots.add(FlSpot(relativeTime, yValue));
>>>>>>> REPLACE
</suggested_fix>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
if (startTime == null) { | ||
startTime = xValue; | ||
minX = 0; | ||
} | ||
|
||
final relativeTime = ((xValue - startTime) / 1000.0); | ||
|
||
spots.add(FlSpot(relativeTime, yValue)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Assumes xValue is in milliseconds for time axis calculation.
If the data source or CSV format changes, this assumption may cause incorrect time calculations. Please validate or document the expected time unit for xValue.
if (startTime == null) { | |
startTime = xValue; | |
minX = 0; | |
} | |
final relativeTime = ((xValue - startTime) / 1000.0); | |
spots.add(FlSpot(relativeTime, yValue)); | |
if (startTime == null) { | |
startTime = xValue; | |
minX = 0; | |
} | |
// Assumes xValue is in milliseconds. If the data source or CSV format changes, | |
// this calculation may be incorrect. Please ensure xValue is in milliseconds. | |
assert(xValue >= 0 && startTime >= 0, 'xValue and startTime should be non-negative and in milliseconds.'); | |
final relativeTime = ((xValue - startTime) / 1000.0); | |
spots.add(FlSpot(relativeTime, yValue)); |
🤦♂️ You are right! I got so many mails from Github that I was confused. Don't ask... 😉 Will fix the problem later today. |
@marcnause I guess you replied on the wrong pull request 😂 |
Fixes #2817
Changes
Screenshots / Recordings
screen-20250807-194558.mp4
Checklist:
strings.xml
,dimens.xml
andcolors.xml
without hard coding any value.strings.xml
,dimens.xml
orcolors.xml
.Summary by Sourcery
Add CSV recording and export capabilities to the gyroscope screen, connect it to the logged data viewer, and enhance charting and storage handling for recorded sensor data
New Features:
Enhancements:
Chores: